#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "StdTcp.h"
#include "StdThread.h"
#include "DoubleLinkList.h"

struct Client
{
    int sock;
    char name[20];
};
typedef struct Client C;

C *createClient(int sock, const char *name)
{
    C *c = (C *)malloc(sizeof(C));
    if (c == NULL)
    {
        printf("createClient malloc error!\n");
        return NULL;
    }
    c->sock = sock;
    strcpy(c->name, name);
    return c;
}

void FreeClient(C *c)
{
    if (c != NULL)
    {
        free(c);
    }
}

struct Message
{
    int flag;
    char fromName[20];
    char toName[20];
    char content[1024];
};

typedef struct Message Msg;

DLlist list;

void *thread_handler(void *arg)
{
    int sock = *(int *)arg;
    while (1)
    {
        Msg msg;

        TcpServerRecv(sock, &msg, sizeof(msg));
        printf("recv flag: %d ,fromname: %s ,toname : %s ,content : %s\n",
               msg.flag, msg.fromName, msg.toName, msg.content);

        switch (msg.flag)
        {
        case 1:
            InsertTail(&list, createClient(sock, msg.fromName));
            break;

        case 2:
            struct Node *travelPoint1 = list.head;
            while (travelPoint1 != NULL)
            {
                C *c = (C *)travelPoint1->data;
                if (strcmp(c->name, msg.toName) == 0)
                {
                    TcpServerSend(c->sock, &msg, sizeof(msg));
                    break;
                }
                travelPoint1 = travelPoint1->next;
            }
            break;

        case 3:
            struct Node *travelPoint2 = list.head;
            while (travelPoint2 != NULL)
            {
                C *c = (C *)travelPoint2->data;
                if (strcmp(c->name, msg.toName) != 0)
                {
                    TcpServerSend(c->sock, &msg, sizeof(msg));
                }
                travelPoint2 = travelPoint2->next;
            }
            break;

        default:
            break;
        }
    }
}

int main(int argc, char *argv[])
{
    if (argc != 3)
    {
        printf("invaild numbers!\n");
        return -1;
    }

    InitDLlist(&list);

    TcpS *s = InitTcpServer(argv[1], atoi(argv[2]));
    if (s == NULL)
    {
        printf("server point is NULL!\n");
        ClearTcpServer(s);
        return -1;
    }

    int acceptSock = 0;
    while ((acceptSock = TcpServerAccept(s)) > 0)
    {
        Thread *t = InitThread(thread_handler, &acceptSock);
        DetachThread(t);
    }

    // int acceptSock = TcpServerAccept(s);
    // if (acceptSock == NULL)
    // {
    //     printf("accept sock = -1!\n");
    //     ClearTcpServer(s);
    //     return -1;
    // }

    // while (1)
    // {
    //     char temp[100] = {0};

    //     TcpServerRecv(acceptSock, temp, 100);
    //     printf("recv : %s\n", temp);
    // }
    // ClearTcpServer(s);
    return 0;
}